package com.cooba.mqtt;

import android.content.Context;
import android.content.Intent;
import android.provider.Settings;
import android.telephony.TelephonyManager;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.ibm.mqtt.MqttClient;
import com.ibm.mqtt.MqttException;
import com.ibm.mqtt.MqttSimpleCallback;

/**
 * MQTT消息发送与接收
 * @author YangSihong
 *
 */
public class MqttBroker {
    private final static Log logger = LogFactory.getLog(MqttBroker.class);// 日志对象
    // 连接参数
    private final static String CONNECTION_STRING = "tcp://120.26.97.23:1883";
    private final static boolean CLEAN_START = true;
    private final static short KEEP_ALIVE = 30;// 低耗网络，但是又需要及时获取数据，心跳30s
    private static String CLIENT_ID = "";// 客户端标识
    private final static int[] QOS_VALUES = { 0 };// 对应主题的消息级别
    private final static String[] TOPICS = { "location"};
    private static MqttBroker instance = new MqttBroker();

    private MqttClient mqttClient;
    private Context context;

    /**
     * 返回实例对象
     *
     * @return
     */
    public MqttBroker getInstance() {
        return instance;
    }

    /**
     * 重新连接服务
     */
    public void connect(String[] topic,int[] qos_values,Context mcontext) throws MqttException {
        context=mcontext;
        String m_szAndroidID = Settings.Secure.getString(mcontext.getContentResolver(), Settings.Secure.ANDROID_ID);
        CLIENT_ID=m_szAndroidID;
        logger.info("connect to mqtt broker.");
        mqttClient = new MqttClient(CONNECTION_STRING);
        logger.info("***********register Simple Handler***********");
        SimpleCallbackHandler simpleCallbackHandler = new SimpleCallbackHandler();
        mqttClient.registerSimpleHandler(simpleCallbackHandler);// 注册接收消息方法
        mqttClient.connect(CLIENT_ID, CLEAN_START, KEEP_ALIVE);
        logger.info("***********subscribe receiver topics***********");
        mqttClient.subscribe(topic, qos_values);// 订阅接主题
        logger.info("***********CLIENT_ID:" + CLIENT_ID);
        // 完成订阅后，可以增加心跳，保持网络通畅，也可以发布自己的消息
        mqttClient.publish("keepalive", "keepalive".getBytes(), QOS_VALUES[0],true);// 增加心跳，保持网络通畅
    }

    /**
     * 发送消息
     *
     * @param topic
     * @param `messageId
     */
    public boolean sendMessage(String topic, String message,Context mcontext) {
        boolean isOK = false;
        try {
            if (mqttClient == null || !mqttClient.isConnected()) {
                String[] topics={topic};
                int[] qos_values={0};
                connect(topics,qos_values,mcontext);
            }

            logger.info("send message to " + topic + ", message is "
                    + message);
            // 发布自己的消息
            mqttClient.publish(topic, message.getBytes(),
                    0, false);
            mqttClient.disconnect();
            isOK = true;
            return isOK;
        } catch (MqttException e) {
            logger.error(e.getCause());
            e.printStackTrace();
        }
        return isOK;
    }

    public void closeMqttClient() throws MqttException{
        if(mqttClient.isConnected()){
            mqttClient.disconnect();
        }
    }
    /**
     * 简单回调函数，处理server接收到的主题消息
     *
     * @author Join
     *
     */
    class SimpleCallbackHandler implements MqttSimpleCallback {

        /**
         * 当客户机和broker意外断开时触发 可以再此处理重新订阅
         */
        @Override
        public void connectionLost() throws Exception {
            // TODO Auto-generated method stub
            System.out.println("客户机和broker已经断开");
        }

        /**
         * 客户端订阅消息后，该方法负责回调接收处理消息
         */
        @Override
        public void publishArrived(String topicName, byte[] payload, int Qos,
                                   boolean retained) throws Exception {
            // TODO Auto-generated method stub
            System.out.println("订阅主题: " + topicName);
            System.out.println("消息数据: " + new String(payload));
            System.out.println("消息级别(0,1,2): " + Qos);
            System.out.println("是否是实时发送的消息(false=实时，true=服务器上保留的最后消息): "
                    + retained);
            Intent intent=new Intent();
            String s = new String(payload);
            intent.putExtra("mqtt_info",s);
            intent.setAction("MQTT_ACTION");
            context.sendBroadcast(intent);
        }

    }

//    public static void main(String[] args) {
//        new MqttBroker().sendMessage("location", "哈喽，123！");
//        /*boolean isOK = MQTTFutureServer.sendMessage("location","1+1=？请回答！");
//        System.out.println(isOK);*/
//    }
}